using System;
using System.Xml;
using System.Xml.Serialization; 
using System.IO;
using System.Collections;

namespace XTCast.Radio 
{

	/// <summary>
	/// Summary description for Config.
	/// </summary>
	
	[XmlRoot("xtcastConfig")]
	public class Config 
	{ 
		private static Config _Config; 

		public Config() 
		{ 
			_Config = this; 
		} 

		static public Config GetConfig() 
		{
			if (_Config==null) 
			{
				Object o = System.Configuration.ConfigurationSettings.GetConfig("xtcastConfig");
				if (typeof(Exception).IsInstanceOfType(o)) 
				{
					_Config = null;
					throw new Exception("Error in XTCast configuration",(Exception)o);
				}
				_Config=(Config)o;
			}
			return _Config; 
		}

		static public StationConfig GetStationConfig(string id) 
		{
			Config c = GetConfig();
			foreach (StationConfig sc in c.Stations) 
			{
				if (String.Compare(id,sc.ID,true)==0) 
				{
					return sc;
				}
			}
			return null;
		}

		public BufferConfig Buffers;

		[XmlArrayAttribute("Locations"), XmlArrayItem("Location", typeof(LocationConfig))] 
		public ArrayList Locations = new ArrayList();

		[XmlArrayAttribute("Stations"), XmlArrayItem("Station", typeof(StationConfig))] 
		public ArrayList Stations = new ArrayList(); 
	}

	public class LocationConfig 
	{ 
		private Config _Config = Config.GetConfig(); 

		public LocationConfig() 
		{
		} 

		[XmlAttributeAttribute()] 
		public string Host="localhost";
		[XmlAttributeAttribute()] 
		public string Application="xtcast";
		[XmlAttributeAttribute()] 
		public string Station;
	}


	public class StationConfig 
	{ 
		private Config _Config = Config.GetConfig(); 

		public StationConfig() 
		{
		} 

		public string DJType 
		{
			get {return "FileDJ";}
		}

		[XmlAttributeAttribute()] 
		public string ID;

		public IdentityConfig Identity;
		public FileDJConfig FileDJ;
		public FormatConfig Format;
	}

	public class IdentityConfig 
	{
		private Config _Config = Config.GetConfig(); 
		
		[XmlAttributeAttribute()] 
		public string Name = "Unknown";

		[XmlAttributeAttribute()] 
		public string Genre = "Unknown";

		[XmlAttributeAttribute()]
		public string HomePage="Default.aspx{1}";

		public string GetHomePage(Uri baseUrl, bool pop) 
		{
			UriBuilder url = new UriBuilder(new Uri(baseUrl,String.Format(HomePage,"?defeatcaching=" + new Random().Next(int.MaxValue))));
			if (pop) url.Scheme="hTtP";
			return url.ToString();
		}
	}

	public class BufferConfig 
	{
		private Config _Config = Config.GetConfig(); 

		public BufferConfig() 
		{
		}

		[XmlAttributeAttribute()] 
		public int Count = 3; 
		[XmlAttributeAttribute()] 
		public int Size = 32768; 
		
		private TimeSpan _Length = TimeSpan.FromSeconds(1);

		[XmlAttributeAttribute("Length")] 
		public string LengthString 
		{ 
			get 
			{ 
				return _Length.ToString(); 
			} 
			set 
			{ 
				_Length = TimeSpan.Parse(value); 
			} 
		} 

		[XmlIgnore()]
		public TimeSpan Length 
		{ 
			get 
			{ 
				return _Length; 
			} 
		}
	}

	public class FormatConfig 
	{

		public FormatConfig() 
		{
		}

		[XmlAttributeAttribute]
		public int Channels = 2;
		[XmlAttributeAttribute]
		public int SampleRate = 44100;
		[XmlAttributeAttribute]
		public int Bitrate = 64000;
		[XmlAttributeAttribute]
		public int MaxBitrate = 500000;
	}

	public class FileDJConfig 
	{ 
		private Config _Config = Config.GetConfig(); 

		public FileDJConfig() 
		{
		}


		public MediaLibraryConfig MediaLibrary;
	} 

	public class MediaLibraryConfig 
	{
		private Config _Config = Config.GetConfig();

		public MediaLibraryConfig() 
		{
		}

		private String[] GetIncludes() 
		{
			ArrayList arr=new ArrayList();
			foreach (XmlElement x in Elements)
				if (x.Name=="Include")
					arr.Add(x.InnerText);
			return (string[])arr.ToArray(typeof(string));
		}

		private String[] GetExcludes() 
		{
			ArrayList arr=new ArrayList();
			foreach (XmlElement x in Elements)
				if (x.Name=="Exclude") 
					arr.Add(x.InnerText);
			arr.Sort();
			return (string[])arr.ToArray(typeof(string));
		}

		string[] _Include;
		public String[] Include 
		{ 
			get 
			{
				if (_Include==null) _Include=GetIncludes();
				return _Include;
			}
		}

		string[] _Exclude;
		public String[] Exclude 
		{ 
			get 
			{
				if (_Exclude==null) _Exclude=GetExcludes();
				return _Exclude;
			}
		}

		[XmlAnyElementAttribute]
		public ArrayList Elements = new ArrayList();
	}
}